package com.promise.jokerdream.database

import android.content.Context
import com.promise.jokerdream.database.account.UserAccount
import com.promise.jokerdream.database.dao.*
import com.promise.jokerdream.database.entity.*
import com.promise.jokerdream.config.user.UserConfig
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withContext

/**
 * 使用 Room 数据库管理用户数据
 */
class UserDataManager private constructor(context: Context) {
    
    private val database: AppDatabase = AppDatabase.getInstance(context)
    private val userAccountDao: UserAccountDao = database.userAccountDao()
    private val currentAccountDao: CurrentAccountDao = database.currentAccountDao()
    private val userConfigDao: UserConfigDao = database.userConfigDao()
    
    // 游戏配置DAO
    private val constellationGameConfigDao: ConstellationGameConfigDao = database.constellationGameConfigDao()
    private val abyssGameConfigDao: AbyssGameConfigDao = database.abyssGameConfigDao()
    private val scratchGameConfigDao: ScratchGameConfigDao = database.scratchGameConfigDao()
    private val mistyGameConfigDao: MistyGameConfigDao = database.mistyGameConfigDao()
    private val penguinFightGameConfigDao: PenguinFightGameConfigDao = database.penguinFightGameConfigDao()
    private val fightTowerGameConfigDao: FightTowerGameConfigDao = database.fightTowerGameConfigDao()
    private val experienceGameConfigDao: ExperienceGameConfigDao = database.experienceGameConfigDao()
    private val ascendHeavenGameConfigDao: AscendHeavenGameConfigDao = database.ascendHeavenGameConfigDao()
    private val wulinGameConfigDao: WulinGameConfigDao = database.wulinGameConfigDao()
    private val mercenaryDispatchGameConfigDao: MercenaryDispatchGameConfigDao = database.mercenaryDispatchGameConfigDao()
    private val immortalsGameConfigDao: ImmortalsGameConfigDao = database.immortalsGameConfigDao()
    private val knightMissionGameConfigDao: KnightMissionGameConfigDao = database.knightMissionGameConfigDao()
    private val worldTreeGameConfigDao: WorldTreeGameConfigDao = database.worldTreeGameConfigDao()
    private val factionCommerceGameConfigDao: FactionCommerceGameConfigDao = database.factionCommerceGameConfigDao()
    private val knightGameConfigDao: KnightGameConfigDao = database.knightGameConfigDao()
    private val arenaGameConfigDao: ArenaGameConfigDao = database.arenaGameConfigDao()
    private val sectGameConfigDao: SectGameConfigDao = database.sectGameConfigDao()
    private val escortGameConfigDao: EscortGameConfigDao = database.escortGameConfigDao()
    private val factionFeedDemoGameConfigDao: FactionFeedDemoGameConfigDao = database.factionFeedDemoGameConfigDao()
    private val otherGameConfigDao: OtherGameConfigDao = database.otherGameConfigDao()
    private val wlmzGameConfigDao: WlmzGameConfigDao = database.wlmzGameConfigDao()
    private val formationGameConfigDao: FormationGameConfigDao = database.formationGameConfigDao()
    private val knightDreamGameConfigDao: KnightDreamGameConfigDao = database.knightDreamGameConfigDao()
    private val currencyExchangeGameConfigDao: CurrencyExchangeGameConfigDao = database.currencyExchangeGameConfigDao()
    private val chaosWarGameConfigDao: ChaosWarGameConfigDao = database.chaosWarGameConfigDao()
    private val sectTournamentGameConfigDao: SectTournamentGameConfigDao = database.sectTournamentGameConfigDao()
    private val knightArenaGameConfigDao: KnightArenaGameConfigDao = database.knightArenaGameConfigDao()
    
    // 任务配置DAO
    private val taskGroupConfigDao: TaskGroupConfigDao = database.taskGroupConfigDao()
    private val taskConfigDao: TaskConfigDao = database.taskConfigDao()
    private val timerTaskConfigDao: TimerTaskConfigDao = database.timerTaskConfigDao()
    
    companion object {
        @Volatile
        private var instance: UserDataManager? = null
        
        fun getInstance(context: Context): UserDataManager {
            return instance ?: synchronized(this) {
                instance ?: UserDataManager(context.applicationContext).also { instance = it }
            }
        }
    }
    
    // ========== UserAccount 操作 ==========
    
    /**
     * 保存用户账户
     */
    fun saveUserAccount(account: UserAccount) {
        runBlocking(Dispatchers.IO) {
            try {
                // 检查账户是否已存在，如果存在则保留原有的创建时间
                val existingEntity = userAccountDao.getByUserId(account.userId)
                val createdAt = existingEntity?.createdAt ?: System.currentTimeMillis()
                
                // 保存账户基本信息
                val entity = UserAccountEntity(
                    userId = account.userId,
                    username = account.username,
                    cookie = account.cookie,
                    createdAt = createdAt
                )
                userAccountDao.insertOrUpdate(entity)
                
                // 保存用户配置
                saveUserConfig(account.userId, account.config)
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }
    }
    
    /**
     * 保存用户配置到数据库
     */
    private suspend fun saveUserConfig(userId: String, config: UserConfig) {
        // 保存 UserConfig 主表
        val userConfigEntity = UserConfigEntity(
            userId = userId,
            lastHourlyWorkExecutedTime = config.lastHourlyWorkExecutedTime
        )
        userConfigDao.insertOrUpdate(userConfigEntity)
        
        // 保存游戏配置到27个独立的表
        config.gameConfig.run {
            constellationConfig.let { constellationGameConfigDao.insertOrUpdate(it.copy(userId = userId)) }
            abyssConfig.let { abyssGameConfigDao.insertOrUpdate(it.copy(userId = userId)) }
            scratchConfig.let { scratchGameConfigDao.insertOrUpdate(it.copy(userId = userId)) }
            mistyConfig.let { mistyGameConfigDao.insertOrUpdate(it.copy(userId = userId)) }
            penguinFightConfig.let { penguinFightGameConfigDao.insertOrUpdate(it.copy(userId = userId)) }
            fightTowerConfig.let { fightTowerGameConfigDao.insertOrUpdate(it.copy(userId = userId)) }
            experienceConfig.let { experienceGameConfigDao.insertOrUpdate(it.copy(userId = userId)) }
            ascendHeavenConfig.let { ascendHeavenGameConfigDao.insertOrUpdate(it.copy(userId = userId)) }
            wulinConfig.let { wulinGameConfigDao.insertOrUpdate(it.copy(userId = userId)) }
            mercenaryDispatchConfig.let { mercenaryDispatchGameConfigDao.insertOrUpdate(it.copy(userId = userId)) }
            immortalsConfig.let { immortalsGameConfigDao.insertOrUpdate(it.copy(userId = userId)) }
            knightMissionConfig.let { knightMissionGameConfigDao.insertOrUpdate(it.copy(userId = userId)) }
            worldTreeConfig.let { worldTreeGameConfigDao.insertOrUpdate(it.copy(userId = userId)) }
            factionCommerceConfig.let { factionCommerceGameConfigDao.insertOrUpdate(it.copy(userId = userId)) }
            knightConfig.let { knightGameConfigDao.insertOrUpdate(it.copy(userId = userId)) }
            arenaConfig.let { arenaGameConfigDao.insertOrUpdate(it.copy(userId = userId)) }
            sectConfig.let { sectGameConfigDao.insertOrUpdate(it.copy(userId = userId)) }
            escortConfig.let { escortGameConfigDao.insertOrUpdate(it.copy(userId = userId)) }
            factionFeedDemoConfig.let { factionFeedDemoGameConfigDao.insertOrUpdate(it.copy(userId = userId)) }
            otherConfig.let { otherGameConfigDao.insertOrUpdate(it.copy(userId = userId)) }
            wlmzConfig.let { wlmzGameConfigDao.insertOrUpdate(it.copy(userId = userId)) }
            formationConfig.let { formationGameConfigDao.insertOrUpdate(it.copy(userId = userId)) }
            knightDreamConfig.let { knightDreamGameConfigDao.insertOrUpdate(it.copy(userId = userId)) }
            currencyExchangeConfig.let { currencyExchangeGameConfigDao.insertOrUpdate(it.copy(userId = userId)) }
            chaosWarConfig.let { chaosWarGameConfigDao.insertOrUpdate(it.copy(userId = userId)) }
            sectTournamentConfig.let { sectTournamentGameConfigDao.insertOrUpdate(it.copy(userId = userId)) }
            knightArenaConfig.let { knightArenaGameConfigDao.insertOrUpdate(it.copy(userId = userId)) }
        }
        
        // 保存任务组配置
        config.taskListConfig.forEach { taskGroup ->
            val groupEntity = taskGroup.copy(userId = userId)
            if (taskGroup.groupId != 0L) {
                taskGroupConfigDao.update(groupEntity)
            } else {
                taskGroupConfigDao.insert(groupEntity)
            }

        }
        
        // 保存定时任务配置
        config.timerTaskConfig.forEach { timerTask ->
            timerTaskConfigDao.insertOrUpdate(timerTask.copy(userId = userId))
        }
    }
    
    /**
     * 获取指定用户账户
     */
    fun getUserAccount(userId: String): UserAccount? {
        return runBlocking(Dispatchers.IO) {
            try {
                val entity = userAccountDao.getByUserId(userId) ?: return@runBlocking null
                val userConfigEntity = userConfigDao.getByUserId(userId)
                val config = userConfigEntity?.toUserConfig(
                    constellationGameConfigDao,
                    abyssGameConfigDao,
                    scratchGameConfigDao,
                    mistyGameConfigDao,
                    penguinFightGameConfigDao,
                    fightTowerGameConfigDao,
                    experienceGameConfigDao,
                    ascendHeavenGameConfigDao,
                    wulinGameConfigDao,
                    mercenaryDispatchGameConfigDao,
                    immortalsGameConfigDao,
                    knightMissionGameConfigDao,
                    worldTreeGameConfigDao,
                    factionCommerceGameConfigDao,
                    knightGameConfigDao,
                    arenaGameConfigDao,
                    sectGameConfigDao,
                    escortGameConfigDao,
                    factionFeedDemoGameConfigDao,
                    otherGameConfigDao,
                    wlmzGameConfigDao,
                    formationGameConfigDao,
                    knightDreamGameConfigDao,
                    currencyExchangeGameConfigDao,
                    chaosWarGameConfigDao,
                    sectTournamentGameConfigDao,
                    knightArenaGameConfigDao,
                    taskGroupConfigDao,
                    taskConfigDao,
                    timerTaskConfigDao
                ) ?: UserConfig()
                
                UserAccount(
                    userId = entity.userId,
                    username = entity.username,
                    cookie = entity.cookie,
                    config = config
                )
            } catch (e: Exception) {
                e.printStackTrace()
                null
            }
        }
    }
    
    /**
     * 获取所有用户账户
     */
    fun getAllUserAccounts(): List<UserAccount> {
        return runBlocking(Dispatchers.IO) {
            try {
                val entities = userAccountDao.getAll()
                entities.map { entity ->
                    val userConfigEntity = userConfigDao.getByUserId(entity.userId)
                    val config = userConfigEntity?.toUserConfig(
                        constellationGameConfigDao,
                        abyssGameConfigDao,
                        scratchGameConfigDao,
                        mistyGameConfigDao,
                        penguinFightGameConfigDao,
                        fightTowerGameConfigDao,
                        experienceGameConfigDao,
                        ascendHeavenGameConfigDao,
                        wulinGameConfigDao,
                        mercenaryDispatchGameConfigDao,
                        immortalsGameConfigDao,
                        knightMissionGameConfigDao,
                        worldTreeGameConfigDao,
                        factionCommerceGameConfigDao,
                        knightGameConfigDao,
                        arenaGameConfigDao,
                        sectGameConfigDao,
                        escortGameConfigDao,
                        factionFeedDemoGameConfigDao,
                        otherGameConfigDao,
                        wlmzGameConfigDao,
                        formationGameConfigDao,
                        knightDreamGameConfigDao,
                        currencyExchangeGameConfigDao,
                        chaosWarGameConfigDao,
                        sectTournamentGameConfigDao,
                        knightArenaGameConfigDao,
                        taskGroupConfigDao,
                        taskConfigDao,
                        timerTaskConfigDao
                    ) ?: UserConfig()
                    
                    UserAccount(
                        userId = entity.userId,
                        username = entity.username,
                        cookie = entity.cookie,
                        config = config
                    )
                }
            } catch (e: Exception) {
                e.printStackTrace()
                emptyList()
            }
        }
    }
    
    /**
     * 删除用户账户
     */
    fun deleteUserAccount(userId: String) {
        runBlocking(Dispatchers.IO) {
            try {
                userAccountDao.deleteByUserId(userId)
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }
    }
    
    // ========== 当前账号管理 ==========
    
    /**
     * 设置当前使用的账号
     */
    fun setCurrentAccount(userId: String) {
        runBlocking(Dispatchers.IO) {
            try {
                val currentAccount = CurrentAccountEntity(id = 1, currentUserId = userId)
                currentAccountDao.insertOrUpdate(currentAccount)
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }
    }
    
    /**
     * 获取当前使用的账号
     */
    fun getCurrentAccount(): UserAccount? {
        return runBlocking(Dispatchers.IO) {
            try {
                val currentAccount = currentAccountDao.getCurrentAccount()
                val currentUserId = currentAccount?.currentUserId
                if (!currentUserId.isNullOrEmpty()) {
                    getUserAccount(currentUserId)
                } else {
                    null
                }
            } catch (e: Exception) {
                e.printStackTrace()
                null
            }
        }
    }
    
    // ========== 任务配置单独更新 ==========

    fun insertTaskGroup(userId: String, taskGroup: TaskGroupConfigEntity) {
        runBlocking(Dispatchers.IO) {
            try {
                taskGroupConfigDao.insert(taskGroup.copy(userId = userId))
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }
    }
    
    /**
     * 更新任务组配置
     */
    fun updateTaskGroup(userId: String, taskGroup: TaskGroupConfigEntity) {
        runBlocking(Dispatchers.IO) {
            try {
                taskGroupConfigDao.update(taskGroup.copy(userId = userId))
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }
    }
    
    /**
     * 更新定时任务配置
     */
    fun updateTimerTask(userId: String, timerTask: TimerTaskConfigEntity) {
        runBlocking(Dispatchers.IO) {
            try {
                timerTaskConfigDao.insertOrUpdate(timerTask.copy(userId = userId))
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }
    }
    
    /**
     * 删除任务配置
     */
    fun deleteTask(taskId: String) {
        runBlocking(Dispatchers.IO) {
            try {
                taskConfigDao.deleteByTaskId(taskId)
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }
    }
    
    /**
     * 删除任务组配置（会级联删除所有关联的任务）
     */
    fun deleteTaskGroup(groupId: Long) {
        runBlocking(Dispatchers.IO) {
            try {
                val groupEntity = taskGroupConfigDao.getByGroupId(groupId)
                if (groupEntity != null) {
                    taskConfigDao.deleteByTaskGroupId(groupEntity.groupId)
                    taskGroupConfigDao.deleteByGroupId(groupId)
                }
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }
    }
    
    /**
     * 删除定时任务配置
     */
    fun deleteTimerTask(taskId: String) {
        runBlocking(Dispatchers.IO) {
            try {
                timerTaskConfigDao.deleteByTaskId(taskId)
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }
    }
    
    /**
     * 获取任务组下的任务数量
     */
    fun getTaskCountByGroupId(taskGroupId: Long): Int {
        return runBlocking(Dispatchers.IO) {
            try {
                taskConfigDao.getTaskCountByGroupId(taskGroupId)
            } catch (e: Exception) {
                e.printStackTrace()
                0
            }
        }
    }
    
    /**
     * 根据任务组ID获取任务列表（suspend 函数，用于协程）
     */
    suspend fun getTasksByGroupId(taskGroupId: Long): List<TaskConfigEntity> {
        return withContext(Dispatchers.IO) {
            try {
                taskConfigDao.getByTaskGroupId(taskGroupId)
            } catch (e: Exception) {
                e.printStackTrace()
                emptyList()
            }
        }
    }
    
    /**
     * 保存任务列表
     */
    suspend fun saveTaskList(taskGroupId: Long, tasks: List<TaskConfigEntity>) {
        withContext(Dispatchers.IO) {
            try {
                // 1. 删除该任务组的所有现有任务
                taskConfigDao.deleteByTaskGroupId(taskGroupId)
                
                // 2. 插入新任务列表
                val tasksWithGroupId = tasks.map { it.copy(id = 0, taskGroupId = taskGroupId) }
                if (tasksWithGroupId.isNotEmpty()) {
                    taskConfigDao.insertOrUpdateAll(tasksWithGroupId)
                }
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }
    }
    
    /**
     * 清理所有账号
     */
    fun clearAllAccounts() {
        runBlocking(Dispatchers.IO) {
            try {
                userAccountDao.deleteAll()
                // 删除所有用户配置
                userAccountDao.getAll().forEach { account ->
                    val userId = account.userId
                    userConfigDao.deleteByUserId(userId)
                    // 删除所有27个游戏配置表的数据
                    constellationGameConfigDao.deleteByUserId(userId)
                    abyssGameConfigDao.deleteByUserId(userId)
                    scratchGameConfigDao.deleteByUserId(userId)
                    mistyGameConfigDao.deleteByUserId(userId)
                    penguinFightGameConfigDao.deleteByUserId(userId)
                    fightTowerGameConfigDao.deleteByUserId(userId)
                    experienceGameConfigDao.deleteByUserId(userId)
                    ascendHeavenGameConfigDao.deleteByUserId(userId)
                    wulinGameConfigDao.deleteByUserId(userId)
                    mercenaryDispatchGameConfigDao.deleteByUserId(userId)
                    immortalsGameConfigDao.deleteByUserId(userId)
                    knightMissionGameConfigDao.deleteByUserId(userId)
                    worldTreeGameConfigDao.deleteByUserId(userId)
                    factionCommerceGameConfigDao.deleteByUserId(userId)
                    knightGameConfigDao.deleteByUserId(userId)
                    arenaGameConfigDao.deleteByUserId(userId)
                    sectGameConfigDao.deleteByUserId(userId)
                    escortGameConfigDao.deleteByUserId(userId)
                    factionFeedDemoGameConfigDao.deleteByUserId(userId)
                    otherGameConfigDao.deleteByUserId(userId)
                    wlmzGameConfigDao.deleteByUserId(userId)
                    formationGameConfigDao.deleteByUserId(userId)
                    knightDreamGameConfigDao.deleteByUserId(userId)
                    currencyExchangeGameConfigDao.deleteByUserId(userId)
                    chaosWarGameConfigDao.deleteByUserId(userId)
                    sectTournamentGameConfigDao.deleteByUserId(userId)
                    knightArenaGameConfigDao.deleteByUserId(userId)
                    // 删除任务配置
                    taskGroupConfigDao.deleteByUserId(userId)
                    timerTaskConfigDao.deleteByUserId(userId)
                }
                currentAccountDao.clear()
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }
    }
}
